package com.xishu.task;

import com.stripe.exception.StripeException;
import com.stripe.model.ApplePayDomain;
import com.stripe.param.ApplePayDomainCreateParams;
import com.xishu.config.Config;
import com.xishu.config.Constant;
import com.xishu.entity.Company;
import com.xishu.entity.User;
import com.xishu.entity.area.Area;
import com.xishu.entity.customer.ScoreHistory;
import com.xishu.entity.order.Order;
import com.xishu.entity.order.OrderCatalogMapping;
import com.xishu.entity.plat.UserCompanyMapping;
import com.xishu.entity.plat.UserShopMapping;
import com.xishu.entity.shop.*;
import com.xishu.exception.ResponseStatusException;
import com.xishu.response.ResponseStatus;
import com.xishu.response.VerifyUtil;
import com.xishu.service.*;
import com.xishu.util.DateUtil;
import com.xishu.util.RandomUtil;
import com.xishu.util.Sha256Util;
import com.xishu.util.Tools;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

public class InitTask implements Tools {
    private static CommonService commonService = CommonService.getInstance();
    private static Logger logger = LoggerFactory.getLogger(InitTask.class);

    private static InitTask instance = new InitTask();

    public InitTask() {
    }

    public static InitTask getInstance() {
        return instance;
    }

    /**
     * 初始化
     */
    public void init() throws Exception {
        User user = new User();
        user.setName("admin");
        List<User> userList = commonService.searchAll(user);

        if (CollectionUtils.isEmpty(userList)) {
            user.setSalt(Sha256Util.generateSalt());
            user.setPassword(Sha256Util.sha256("admin", user.getSalt()));
            user.setAdmin(true);
            user.setDescription("admin user");
            try {
                commonService.createObject(user);
            } catch (Exception e) {
                logger.error("e", e);
            }
        } else {
            User adminUser = userList.get(0);
            if (isEmpty(adminUser.getPassword())) {
                String salt = Sha256Util.generateSalt();
                adminUser.setSalt(salt);
                adminUser.setPassword(Sha256Util.sha256("admin", salt));
                commonService.save(adminUser);
            }
        }
    }

    /**
     * 初始化地区
     */
    public void initArea() throws Exception {
        Area area = new Area();
        List<Area> areaList = CommonService.getInstance().searchAll(area);

        //插入数据
        if (isEmpty(areaList)) {
            Area 香港 = new Area();
            香港.setLevel(Constant.PROVINCE_LEVEL);
            香港.setName("香港特別行政區");
            香港.setName_zh("香港特別行政區");
            香港.setName_en("Hong Kong SAR");
            commonService.createObject(香港);

            Area 香港岛 = createArea("港島", "Hong Kong Island", 香港.getId(), Constant.CITY_LEVEL);
            Area 九龙 = createArea("九龍", "Kowloon", 香港.getId(), Constant.CITY_LEVEL);
            Area 新界 = createArea("新界", "New Territories", 香港.getId(), Constant.CITY_LEVEL);

            createArea("中西區", "Central and Western", 香港岛.getId(), Constant.COUNTY_LEVEL);
            createArea("灣仔區", "Wan Chai", 香港岛.getId(), Constant.COUNTY_LEVEL);
            createArea("東區", "Eastern", 香港岛.getId(), Constant.COUNTY_LEVEL);
            createArea("南區", "Southern", 香港岛.getId(), Constant.COUNTY_LEVEL);

            createArea("油尖旺", "Yau Tsim Mong", 九龙.getId(), Constant.COUNTY_LEVEL);
            createArea("深水埗", "Sham Shui Po", 九龙.getId(), Constant.COUNTY_LEVEL);
            createArea("九龍城", "Kowloon City", 九龙.getId(), Constant.COUNTY_LEVEL);
            createArea("黄大仙", "Wong Tai Sin", 九龙.getId(), Constant.COUNTY_LEVEL);
            createArea("觀塘", "Kwun Tong", 九龙.getId(), Constant.COUNTY_LEVEL);

            createArea("荃灣", "Tsuen Wan", 新界.getId(), Constant.COUNTY_LEVEL);
            createArea("屯門", "Tuen Mun", 新界.getId(), Constant.COUNTY_LEVEL);
            createArea("元朗", "Yuen Long", 新界.getId(), Constant.COUNTY_LEVEL);
            createArea("北區", "North", 新界.getId(), Constant.COUNTY_LEVEL);
            createArea("大埔", "Tai Po", 新界.getId(), Constant.COUNTY_LEVEL);
            createArea("西貢", "Sai Kung", 新界.getId(), Constant.COUNTY_LEVEL);
            createArea("沙田", "Sha Tin", 新界.getId(), Constant.COUNTY_LEVEL);
            createArea("葵青", "Kwai Tsing", 新界.getId(), Constant.COUNTY_LEVEL);
            createArea("離島", "Islands", 新界.getId(), Constant.COUNTY_LEVEL);
        }

    }

    private Area createArea(String name, String name_en, Long parentId, Integer level) throws Exception {
        Area area = new Area();
        area.setLevel(level);
        area.setName(name);
        area.setName_zh(name);
        area.setName_en(name_en);
        area.setParentId(parentId);
        commonService.createObject(area);
        return area;
    }

    /**
     * 模拟数据
     */
    public void mockData() throws Exception {
        Config config = Config.getInstance();

        if (!config.isSingleNode()) {
            return;
        }

        CommonService commonService = CommonService.getInstance();
        List<Company> companyList = commonService.searchAll(new Company());

        //创建商家
        if (isEmpty(companyList)) {
            Company company = new Company();
            company.setName("成都西鼠");
            company.setCompanyAddress("成都");
            company.setCode("123456");

            commonService.createObject(company);
        }

        //创建分店
        List<Shop> shopList = commonService.searchAll(new Shop());
        if (isEmpty(shopList)) {
            List<Company> list = commonService.searchAll(new Company());
            Company company = list.get(0);
            Shop shop = new Shop();
            shop.setName("成都西鼠");
            shop.setPhone("13688318987");
            shop.setCompanyName(shop.getName());

            shop.setCompanyId(company.getId());

            commonService.createObject(shop);
            shop.setShopId(shop.getId());
            commonService.directSave(shop);

            //添加排队设置
            createLineUpConfig(shop.getId(), 2, "A");
            createLineUpConfig(shop.getId(), 4, "B");
            createLineUpConfig(shop.getId(), 6, "C");
            createLineUpConfig(shop.getId(), 8, "D");
            createLineUpConfig(shop.getId(), 10, "E");
        }

        //插入假的订单数据
        List<OrderCatalogMapping> orderCatalogMappingList = commonService.searchAll(OrderCatalogMapping.class);
        if (isEmpty(orderCatalogMappingList)) {
            long timeMillis = System.currentTimeMillis();
            for (int i = 0; i < 20; i++) {
                OrderCatalogMapping orderCatalogMapping = new OrderCatalogMapping();
                orderCatalogMapping.setCatalogId(1l);
                orderCatalogMapping.setOrderId(1l);
                orderCatalogMapping.setShopId(1l);
                orderCatalogMapping.setCatalogName("catalogName");
                orderCatalogMapping.setCash(Double.valueOf(i));

                orderCatalogMapping.setCreateTime(timeMillis - i * DateUtil.ONE_MONTH);
                commonService.createObject(orderCatalogMapping);
            }
        }
    }

    /**
     * 插入假的排队数据
     *
     * @param shopId
     * @param maxLinePersons
     * @param code
     * @throws IllegalAccessException
     * @throws ResponseStatusException
     * @throws InstantiationException
     */
    private void createLineUpConfig(Long shopId, Integer maxLinePersons, String code) throws Exception {
        LineUpConfig lineUpConfig = new LineUpConfig();
        lineUpConfig.setMaxLinePersons(maxLinePersons);
        lineUpConfig.setShopId(shopId);
        lineUpConfig.setOnlineShow(true);
        lineUpConfig.setOfflineShow(true);
        lineUpConfig.setCode(code);
        CommonService.getInstance().createObject(lineUpConfig);
    }

    /**
     * 将所有的消费后金额的优惠卷初始化
     */
    public void initAfterCostTicket() {

    }

    public void mockAddItem() throws Exception {
        Item item = commonService.findEntity(39l, Item.class);
        for (int i = 0; i < 200; i++) {
            try {
                Item newItem = new Item();
                BeanUtils.copyProperties(item, newItem);
                logger.info("will create item, {}", JSONObject.fromObject(newItem));
                newItem.setId(null);
                CommonService.getInstance().createObject(newItem);
                CatalogItemMapping catalogItemMapping = new CatalogItemMapping();
                catalogItemMapping.setCatalogId(32l);
                catalogItemMapping.setItemName("菜品");
                catalogItemMapping.setItemId(newItem.getId());
                CommonService.getInstance().createObject(catalogItemMapping);
            } catch (Exception e) {
                logger.error("e", e);
            }
        }
    }

    public void updateMockItem() {
        Item reqItem = new Item();
        reqItem.setCompanyId(114l);
        List<Item> itemList = CommonService.getInstance().searchAll(reqItem);
        itemList.forEach(item -> {
            try {
                ArrayList<PriceConfig> list = new ArrayList<>();
                PriceConfig priceConfig = new PriceConfig();
                priceConfig.setSceneId(36l);
                priceConfig.setPrice(20d);
                priceConfig.setEnable(true);
                priceConfig.setSceneName("全天");
                list.add(priceConfig);
                item.setPriceConfigList(list);
                CommonService.getInstance().save(item);
            } catch (Exception e) {
                logger.error("e", e);
            }
        });
    }

    /**
     * 如果没有运营模式的，添加
     *
     * @throws Exception
     */
    public void updateRunModel() throws Exception {
        List<Shop> shopList = commonService.searchAll(Shop.class);

        for (Shop shop : shopList) {
            ShopService.getInstance().createRunModel(shop.getId());
        }
    }

    /**
     * 更新成非套餐
     *
     * @throws Exception
     */
    public void updateItem() throws Exception {
        List<Item> itemList = commonService.searchAll(Item.class);
        for (Item item : itemList) {
            if (item.getSetMenu() == null) {
                item.setSetMenu(false);
                commonService.save(item);
            }

            if (item.getPrice() != null && item.getPrice() == 0d && isNotEmpty(item.getPriceConfigList())) {
                item.setPrice(null);
                commonService.save(item);
            }

            if (item.getCatalogId() == null) {
                CatalogItemMapping catalogItemMapping = new CatalogItemMapping();
                catalogItemMapping.setEntity(true);
                catalogItemMapping.setItemId(item.getId());
                Optional<CatalogItemMapping> catalogItemMappingOptional = commonService.searchOneOptional(catalogItemMapping);
                if (catalogItemMappingOptional.isPresent()) {
                    item.setCatalogId(catalogItemMappingOptional.get().getCatalogId());
                    commonService.save(item);
                }
            }

            CatalogItemService.getInstantce().syncItemImgToCatalogItemMapping(item.getId());
        }
    }

    public void updateCatalogItemMapping() throws Exception {
        List<CatalogItemMapping> catalogItemMappings = commonService.searchAll(CatalogItemMapping.class);
        for (CatalogItemMapping catalogItemMapping : catalogItemMappings) {

            if (isEmpty(catalogItemMapping.getCatalogName())) {
                Catalog catalog = commonService.findEntity(catalogItemMapping.getCatalogId(), Catalog.class);
                catalogItemMapping.setCatalogName(catalog.getName());
                commonService.save(catalogItemMapping);
            }

            if (catalogItemMapping.getLeftCount() == null) {
                Item item = commonService.findEntity(catalogItemMapping.getItemId(), Item.class);
                catalogItemMapping.setLeftCount(item.getLeftCount());
                commonService.save(catalogItemMapping);
            }
        }
    }

    public void updateFoodTableTemplateValue() throws Exception {
        List<FoodTable> foodTableList = commonService.searchAll(FoodTable.class);
        for (FoodTable foodTable : foodTableList) {
            if (getBoolean(foodTable.getDefaultFoodTable())) {
                foodTable.setTemplate(false);
                commonService.save(foodTable);
            }
        }
    }

    public void updateShopName() throws Exception {
        List<Shop> shops = commonService.searchAll(new Shop());
        for (Shop shop : shops) {
            ZhEnService.getInstance().syncZhEn(shop);
            commonService.save(shop);
        }
    }

    public void updateCompanyName() throws Exception {
        List<Company> companyList = commonService.searchAll(new Company());
        for (Company company : companyList) {
            ZhEnService.getInstance().syncZhEn(company);
            commonService.save(company);
        }
    }

    public void updateItemDetail() throws Exception {
        List<Item> itemList = commonService.searchAll(new Item());
        for (Item item : itemList) {
            if (isNotEmpty(item.getItemDetailList())) {
                List<ItemDetail> itemDetailList = item.getItemDetailList().stream().filter(p -> isNotEmpty(p.getName())).collect(Collectors.toList());
                item.setItemDetailList(itemDetailList);

                //再判断有没有ID，没有ID的，都加上ID
                for (ItemDetail itemDetail : itemDetailList) {
                    if (getLong(itemDetail.getId()) == 0) {
                        Long itemIndex = ItemService.getInstance().generateItemIndex();
                        itemDetail.setId(itemIndex);
                    }

                    List<NameAndPrice> nameAndPriceList = itemDetail.getNameAndPriceList();
                    if (isNotEmpty(nameAndPriceList)) {
                        for (NameAndPrice nameAndPrice : nameAndPriceList) {
                            if (getLong(nameAndPrice.getId()) == 0) {
                                Long itemIndex = ItemService.getInstance().generateItemIndex();
                                nameAndPrice.setId(itemIndex);
                            }
                        }
                    }
                }

                commonService.save(item);
            }
        }
    }

    public void updateItemCatalogName() throws Exception {
        List<CatalogItemMapping> catalogItemMappingList = commonService.searchAll(new CatalogItemMapping());
        if (isNotEmpty(catalogItemMappingList)) {
            for (CatalogItemMapping catalogItemMapping : catalogItemMappingList) {
                MappingService.getInstance().syncItemCatalogName(catalogItemMapping);
            }
        }
    }

    public void initApplePay() throws StripeException {
        if (Config.getInstance().isAliyun()) {
            ApplePayDomainCreateParams appleDomainParams =
                    ApplePayDomainCreateParams.builder()
                            .setDomainName("xishu.3g48.com")
                            .build();

            ApplePayDomain.create(appleDomainParams);
        } else {
            ApplePayDomainCreateParams appleDomainParams =
                    ApplePayDomainCreateParams.builder()
                            .setDomainName("xishu.3g48.com")
                            .build();

            ApplePayDomain.create(appleDomainParams);
        }
    }

    public void updateCompany() throws Exception {
        List<Company> companyList = commonService.searchAll(Company.class);
        for (Company company : companyList) {
            if (company.getPass() == null) {
                company.setPass(false);
                commonService.save(company);
            }
        }
    }

    public void resetCatalogItemMapping() throws Exception {
        List<CatalogItemMapping> catalogItemMappings = commonService.searchAll(CatalogItemMapping.class);
        for (CatalogItemMapping catalogItemMapping : catalogItemMappings) {
            if (catalogItemMapping.getShopId() == null) {
                try {
                    Item item = ItemService.getInstance().findItem(catalogItemMapping.getItemId());
                    catalogItemMapping.setShopId(item.getShopId());
                    commonService.save(catalogItemMapping);
                } catch (Exception e) {
                    logger.error("e", e);
                }
            }
        }
    }

    /**
     * 更新场景配置
     */
    public void updateSceneConfig() throws Exception {
        List<Shop> shopList = ShopService.getInstance().findAllShop();

        //将分店的配置复制到场景下面去
        for (Shop shop : shopList) {
            migrateConfigToScene(shop);
        }
    }

    /**
     * 将配置迁移到场景下面
     *
     * @param shop
     * @throws Exception
     */
    public void migrateConfigToScene(Shop shop) throws Exception {
        Scene scene = new Scene();
        scene.setShopId(shop.getId());
        List<Scene> sceneList = commonService.searchAll(scene);

        for (Scene sceneInDb : sceneList) {
            if (sceneInDb.getSendToKitchenAutoPrintOrderInB() == null
                    && sceneInDb.getSendToKitchenAutoPrintOrderInC() == null
                    && sceneInDb.getServiceFeePercent() == null
                    && sceneInDb.getTakeoutFeePercent() == null) {
                sceneInDb.setSendToKitchenAutoPrintOrderInB(shop.getShopConfig().getSendToKitchenAutoPrintOrderInB());
                sceneInDb.setSendToKitchenAutoPrintOrderInB(shop.getShopConfig().getSendToKitchenAutoPrintOrderInC());
                sceneInDb.setServiceFeePercent(shop.getServiceFeePercent());
                sceneInDb.setTakeoutFeePercent(shop.getTakeoutFeePercent());

                commonService.save(sceneInDb);
            }
        }
    }

    /**
     * 删除废弃的映射关系
     */
    public void removeMapping() throws Exception {
        CommonService commonService = CommonService.getInstance();
        List<UserShopMapping> userShopMappings = commonService.searchAll(UserShopMapping.class);
        userShopMappings = userShopMappings.stream().filter(p -> {
            //过滤不存在的用户
            try {
                return !UserService.getInstance().isUserExist(p.getUserId());
            } catch (Exception e) {
                logger.error("e", e);
                return true;
            }
        }).collect(Collectors.toList());

        for (UserShopMapping userShopMapping : userShopMappings) {
            commonService.delete(userShopMapping, false);
        }


        List<UserCompanyMapping> userCompanyMappingList = commonService.searchAll(UserCompanyMapping.class);

        userCompanyMappingList = userCompanyMappingList.stream().filter(p -> {
            //过滤不存在的用户
            try {
                return !UserService.getInstance().isUserExist(p.getUserId());
            } catch (Exception e) {
                logger.error("e", e);
                return true;
            }
        }).collect(Collectors.toList());

        for (UserCompanyMapping userCompanyMapping : userCompanyMappingList) {
            commonService.delete(userCompanyMapping);
        }
    }

    /**
     * 更新品类的数据
     */
    public void updateCatalogData() throws Exception {
        List<Catalog> catalogList = commonService.searchAll(Catalog.class);
        for (Catalog catalog : catalogList) {
            if (isNotEmpty(catalog.getSceneList())) {
                catalog.setTimeConfigList(null);
                catalog.setTimeConfigJson(null);
                commonService.save(catalog);
            }
        }

    }

    public void insertMockScoreHistory() throws Exception {
        for (int j = 0; j < 10; j++) {

            for (int i = 0; i < 10; i++) {
                ScoreHistory scoreHistory = new ScoreHistory();
                scoreHistory.setCustomerId((long) (j + 1));

                String s = RandomUtil.generateNumberCode(4);
                if (i % 2 == 0) {
                    scoreHistory.setChangeType(1);
                    scoreHistory.setValue(Integer.valueOf(s));
                } else {
                    scoreHistory.setChangeType(2);
                    scoreHistory.setValue(-Integer.valueOf(s));
                }

                commonService.createObject(scoreHistory);
            }
        }
    }

    /**
     * 将现有的菜品数据插入到公司的主菜当中
     */
    public void insertCompanyMainItem() throws Exception {
        CustomerService customerService = CustomerService.getInstance();
        ItemService itemService = ItemService.getInstance();
        List<Company> companyList = commonService.searchAll(Company.class);
        for (Company company : companyList) {
            List<Item> itemList = itemService.findAllItemByCompanyId(company.getId());
            logger.info("company is {}, item size is {} ", company.getId(), itemList.size());
            for (Item item : itemList) {
                if (isNotEmpty(item.getName_zh())) {
                    Optional<CompanyMainItem> companyMainItemOptional = customerService.isCompanyMainItemExist(company.getId(), item.getName_zh(), getBoolean(item.getSetMenu()) ? 1 : 0);
                    //不存在，则创建一个
                    if (!companyMainItemOptional.isPresent()) {
                        CompanyMainItem companyMainItem = new CompanyMainItem();
                        companyMainItem.setCompanyId(company.getId());
                        companyMainItem.setName_zh(item.getName_zh());
                        companyMainItem.setName_en(item.getName_en());
                        if (getBoolean(item.getSetMenu())) {
                            companyMainItem.setItemType(1);
                        } else {
                            companyMainItem.setItemType(0);
                        }

                        commonService.createObject(companyMainItem);

                        //添加主菜的ID
                        item.setMainItemId(companyMainItem.getId());
                        commonService.save(item);
                        continue;
                    }

                    if (Config.getInstance().forceUpdateCompanyMainItem()) {
                        item.setMainItemId(companyMainItemOptional.get().getId());
                    } else if (item.getMainItemId() == null) {
                        item.setMainItemId(companyMainItemOptional.get().getId());
                        commonService.save(item);
                    }
                }
            }
        }
    }

    /**
     * 初始化订单菜品数量
     */
    public void intOrderNoService() throws ResponseStatusException {
        // TODO: 2022/3/7 一定要查询到有菜的订单，不能数据会错乱
        List<Order> orderList = CommonService.getInstance().findLimit(new Order(), 500);
        OptionalLong orderItemNo = orderList.stream().flatMap(order -> getList(order.getOrderItemDetailList()).stream()).mapToLong(item -> getLong(item.getId())).max();
        long number = 1000;

        if (isNotEmpty(orderList) && !orderItemNo.isPresent()) {
            VerifyUtil.throwError(ResponseStatus.SYSTEM_ERROR);
        }

        if (orderItemNo.isPresent()) {
            number = orderItemNo.getAsLong();
        }

        logger.info("the order item no is {}", number);

        OrderNoService.getInstance().setOrderItemNo(new AtomicLong(number));
    }
}
